package com.ruoyi.web.controller.store.in;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.*;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.RestaurantStoreResourceMapper;
import com.ruoyi.system.mapper.StoreInMapper;
import com.ruoyi.system.service.RestaurantStoreResourceService;
import com.ruoyi.system.service.StoreInDetailService;
import com.ruoyi.system.service.StorePlanDetailService;
import com.ruoyi.system.service.resp.StoreInDetailDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: ruohao
 * @Date: 2023/10/14
 **/
@RestController
@RequestMapping("/store/in/detail")
@Api(tags = "入库单明细相关接口")
public class StoreInDetailController extends BaseController {
    @Resource
    private StoreInDetailService storeInDetailService;

    @Resource
    private RestaurantStoreResourceService restaurantStoreResourceService;

    @Resource
    private StorePlanDetailService storePlanDetailService;
    @Resource
    RestaurantStoreResourceMapper storeResourceMapper;

    @Resource
    private StoreInMapper storeInMapper;

    @Log(title = "获取入库单明细", businessType = BusinessType.OTHER)
    @GetMapping("/listAll")
    public TableDataInfo listAll(StoreInDetail storeInDetail) {
        List<StoreInDetail> storeInDetails = storeInDetailService.selectList(storeInDetail);
        return getDataTable(fillToDTOs(storeInDetails));
    }

    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable Long id) {
        return success((storeInDetailService.selectById(id)));
    }

    @ApiOperation("增加入库单明细")
    @Log(title = "增加入库单明细", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@Validated @RequestBody StoreInDetail storeInDetail) {
        if (isBuffet(storeInDetail.getInId())) {
            storeInDetail.setDirect("是");
        } else {
            storeInDetail.setDirect("否");
        }
//园区为全部的不让新增
        if (StringUtils.isNotBlank(SecurityUtils.getUserLocation()) && SecurityUtils.getUserLocation().equals("全部")) {
            throw new BaseException("错误,该登录人园区为全部,不允许新增");
        }
//        StoreIn storeIn = storeInMapper.selectById(storeInDetail.getInId());
//        if (storeIn == null) {
//            throw new BaseException("未找到入库单");
//        }
//        if (StringUtils.isNotBlank(storeIn.getStatus()) && storeIn.getStatus().equals("已入库")) {
//            throw new BaseException("该入库单已出库,无法变更");
//        }

        storeInDetail.setPrice(storeResourceMapper.getPrice(storeInDetail.getResourceId()));
        storeInDetail.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        Boolean result = storeInDetailService.create(storeInDetail);
        if (result) {
            return success();
        }
        return error();
    }

    private boolean isBuffet(Long storeInId) {
        if (storeInId == null) {
            return false;
        }
        StoreIn storeIn = storeInMapper.selectById(storeInId);
        if (storeIn == null) {
            return false;
        }
        return "自助餐入库单".equals(storeIn.getType());
    }

    @ApiOperation("编辑入库单明细")
    @Log(title = "编辑入库单明细", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody StoreInDetail storeInDetail) {
        logger.info("编辑入库单明细 {}", JSON.toJSONString(storeInDetail));

//        StoreIn storeIn = storeInMapper.selectById(storeInDetail.getInId());
//        if (storeIn == null) {
//            throw new BaseException("未找到入库单");
//        }
//        if (StringUtils.isNotBlank(storeIn.getStatus()) && storeIn.getStatus().equals("已入库")) {
//            throw new BaseException("该入库单已出库,无法变更");
//        }

        storeInDetail.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        Boolean result = storeInDetailService.update(storeInDetail);
        if (result) {
            return success();
        }
        return error();
    }

    @ApiOperation("删除入库单明细")
    @Log(title = "删除入库单明细", businessType = BusinessType.DELETE)
    @DeleteMapping("/{id}")
    public AjaxResult remove(@PathVariable Long id) {
        StoreInDetail storeInDetail = storeInDetailService.selectById(id);

//        StoreIn storeIn = storeInMapper.selectById(storeInDetail.getInId());
//        if (storeIn == null) {
//            throw new BaseException("未找到入库单");
//        }
//        if (StringUtils.isNotBlank(storeIn.getStatus()) && storeIn.getStatus().equals("已入库")) {
//            throw new BaseException("该入库单已出库,无法变更");
//        }
        return toAjax(storeInDetailService.deleteById(id));
    }

    private List<StoreInDetailDTO> fillToDTOs(List<StoreInDetail> storeInDetails) {
        if (CollectionUtils.isEmpty(storeInDetails)) {
            return Collections.emptyList();
        }
        // 食材map
        List<Long> resourceIds = storeInDetails.stream().map(StoreInDetail::getResourceId).collect(Collectors.toList());
        List<RestaurantStoreResource> resources = restaurantStoreResourceService.selectRestaurantStoreResourceByIds(resourceIds);
        Map<Long, RestaurantStoreResource> resourceMap;
        if (!CollectionUtils.isEmpty(resources)) {
            resourceMap = resources.stream().collect(Collectors.toMap(RestaurantStoreResource::getId, r -> r));
        } else {
            resourceMap = new HashMap<>();
        }
        // 计划详情map
        List<Long> planDetailIds = storeInDetails.stream().map(StoreInDetail::getPlanDetailId).collect(Collectors.toList());
        List<StorePlanDetail> storePlanDetails = storePlanDetailService.selectByIds(planDetailIds);
        Map<Long, StorePlanDetail> storePlanDetailMap;
        if (!CollectionUtils.isEmpty(storePlanDetails)) {
            storePlanDetailMap = storePlanDetails.stream().collect(Collectors.toMap(StorePlanDetail::getId, s -> s));
        } else {
            storePlanDetailMap = new HashMap<>();
        }
        return storeInDetails.stream().map(s -> {
            StoreInDetailDTO storeInDetailDTO = new StoreInDetailDTO();
            storeInDetailDTO.setId(s.getId());
            storeInDetailDTO.setResourceId(s.getResourceId());
            storeInDetailDTO.setResourceName(Optional.ofNullable(resourceMap.get(s.getResourceId())).map(RestaurantStoreResource::getName).orElse(null));
            storeInDetailDTO.setPlanDetailId(s.getPlanDetailId());
            storeInDetailDTO.setUnit(Optional.ofNullable(storePlanDetailMap.get(s.getPlanDetailId())).map(StorePlanDetail::getUnit).orElse(null));
            storeInDetailDTO.setPlanAmount(Optional.ofNullable(storePlanDetailMap.get(s.getPlanDetailId())).map(StorePlanDetail::getAmount).orElse(null));
            storeInDetailDTO.setAmount(s.getAmount());
            storeInDetailDTO.setStatus(s.getStatus());
            storeInDetailDTO.setPrice(s.getPrice());
            storeInDetailDTO.setDirect(s.getDirect());
            storeInDetailDTO.setCreateBy(s.getCreateBy());
            storeInDetailDTO.setCreateTime(s.getCreateTime());
            storeInDetailDTO.setUpdateBy(s.getUpdateBy());
            storeInDetailDTO.setUpdateTime(s.getUpdateTime());
            storeInDetailDTO.setRemark(s.getRemark());
            storeInDetailDTO.setPrice(s.getPrice());
            storeInDetailDTO.setResourceName(storeResourceMapper.getName(storeInDetailDTO.getResourceId()));
            storeInDetailDTO.setName(storeResourceMapper.getName(storeInDetailDTO.getResourceId()));
            return storeInDetailDTO;
        }).collect(Collectors.toList());
    }
}
